﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ibuddylib {
    public class BuddyAnimator : IDisposable {
        private IBuddy buddy;
        private Timeline timeline;

        public IBuddy Buddy { 
            get {
                return buddy;
            }
        }

        public BuddyAnimator(IBuddy buddy) {
            this.buddy = buddy;
            this.timeline = new Timeline();
        }

        ~BuddyAnimator() {
            Dispose();
        }

        /// <summary>
        /// Turn the i-Buddy's body to the other side
        /// </summary>
        public void Twist() {
            buddy.TorsoYaw = buddy.TorsoYaw == TorsoYaw.Left ? TorsoYaw.Right : TorsoYaw.Left;
        }

        /// <summary>
        /// Flap the i-Buddy's wings once (put the wings in the other position)
        /// </summary>
        public void Wag() {
            buddy.WingPosition = buddy.WingPosition == WingPosition.High ? WingPosition.Low : WingPosition.High;
        }

        /// <summary>
        /// Flap the wings for 200ms
        /// </summary>
        public void Flap() {
            Flap(200);
        }

        /// <summary>
        /// Flap the wings for a given duration in ms
        /// </summary>
        /// <param name="ms"></param>
        public void Flap(int ms) {
            timeline.ScheduleIn(0, WingsHigh);
            timeline.ScheduleIn(ms, WingsLow);
        }

        /// <summary>
        /// Invert the state of the i-Buddy's heart light
        /// </summary>
        public void InvertHeart() {
            buddy.HeartLight = buddy.HeartLight == HeartLight.On ? HeartLight.Off : HeartLight.On;
        }

        /// <summary>
        /// Beat the heart for the given duration
        /// </summary>
        public void HeartBeat(int ms) {
            timeline.ScheduleIn(0, HeartOn);
            timeline.ScheduleIn(ms, HeartOff);
        }

        /// <summary>
        /// Flash to the given head color for the given duration, then go back to the current color
        /// </summary>
        /// <param name="which"></param>
        /// <param name="ms"></param>
        public void FlashColor(HeadColor which, int ms) {
            HeadColor current = buddy.HeadColor;
            timeline.ScheduleIn(0, delegate() { buddy.HeadColor = which; });
            timeline.ScheduleIn(ms, delegate() { buddy.HeadColor = current; });
        }

        /// <summary>
        /// Flash to the given head color for 200ms
        /// </summary>
        /// <param name="which"></param>
        public void FlashColor(HeadColor which) {
            FlashColor(which, 200);
        }

        /// <summary>
        /// Beat the heart for 500ms.
        /// </summary>
        public void HeartBeat() {
            HeartBeat(250);
        }

        private void HeartOn() {
            buddy.HeartLight = HeartLight.On;
        }

        private void HeartOff() {
            buddy.HeartLight = HeartLight.Off;
        }

        private void WingsHigh() {
            buddy.WingPosition = WingPosition.High;
        }

        private void WingsLow() {
            buddy.WingPosition = WingPosition.Low;
        }

        #region IDisposable Members

        public void Dispose() {
            timeline.Dispose();
        }

        #endregion
    }
}
